home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / UNIXTOOL / M4SRC / _files / _M4 / Eval._C next >
Encoding:
Text File  |  1989-10-15  |  5.5 KB  |  333 lines

  1. /*
  2.  * eval.c
  3.  * Facility: m4 macro processor
  4.  * by: oz
  5.  */
  6.  
  7. #include "mdef.h"
  8. #include "extr.h"
  9.  
  10. #include <string.h>
  11. #include <stdlib.h>
  12.  
  13. /*
  14.  * eval - evaluate built-in macros.
  15.  *      argc - number of elements in argv.
  16.  *      argv - element vector :
  17.  *            argv[0] = definition of a user
  18.  *                  macro or nil if built-in.
  19.  *            argv[1] = name of the macro or
  20.  *                  built-in.
  21.  *            argv[2] = parameters to user-defined
  22.  *               .      macro or built-in.
  23.  *               .
  24.  *
  25.  * Note that the minimum value for argc is 3. A call in the form
  26.  * of macro-or-builtin() will result in:
  27.  *            argv[0] = nullstr
  28.  *            argv[1] = macro-or-builtin
  29.  *            argv[2] = nullstr
  30.  *
  31.  */
  32.  
  33. void eval (char *argv[], int argc, int td)
  34. {
  35.     register int c, n;
  36.     static int sysval;
  37.  
  38. #ifdef DEBUG
  39.     printf("argc = %d\n", argc);
  40.     for (n = 0; n < argc; n++)
  41.         printf("argv[%d] = %s\n", n, argv[n]);
  42. #endif
  43.     /*
  44.      * if argc == 3 and argv[2] is null,
  45.      * then we have macro-or-builtin() type call.
  46.      * We adjust argc to avoid further checking..
  47.      *
  48.      */
  49.     if (argc == 3 && !*(argv[2]))
  50.         argc--;
  51.  
  52.     switch (td & ~STATIC) {
  53.  
  54.     case DEFITYPE:
  55.         if (argc > 2)
  56.             dodefine(argv[2], (argc > 3) ? argv[3] : null);
  57.         break;
  58.  
  59.     case PUSDTYPE:
  60.         if (argc > 2)
  61.             dopushdef(argv[2], (argc > 3) ? argv[3] : null);
  62.         break;
  63.  
  64.     case DUMPTYPE:
  65.         dodump(argv, argc);
  66.         break;
  67.  
  68.     case EXPRTYPE:
  69.         /*
  70.          * doexpr - evaluate arithmetic expression
  71.          *
  72.          */
  73.         if (argc > 2)
  74.             pbnum(expr(argv[2]));
  75.         break;
  76.  
  77.     case IFELTYPE:
  78.         if (argc > 4)
  79.             doifelse(argv, argc);
  80.         break;
  81.  
  82.     case IFDFTYPE:
  83.         /*
  84.          * doifdef - select one of two alternatives based
  85.          *         on the existence of another definition
  86.          */
  87.         if (argc > 3) {
  88.             if (lookup(argv[2]) != nil)
  89.                 pbstr(argv[3]);
  90.             else if (argc > 4)
  91.                 pbstr(argv[4]);
  92.         }
  93.         break;
  94.  
  95.     case LENGTYPE:
  96.         /*
  97.          * dolen - find the length of the argument
  98.          *
  99.          */
  100.         if (argc > 2)
  101.             pbnum((argc > 2) ? strlen(argv[2]) : 0);
  102.         break;
  103.  
  104.     case INCRTYPE:
  105.         /*
  106.          * doincr - increment the value of the argument
  107.          *
  108.          */
  109.         if (argc > 2)
  110.             pbnum(atoi(argv[2]) + 1);
  111.         break;
  112.  
  113.     case DECRTYPE:
  114.         /*
  115.          * dodecr - decrement the value of the argument
  116.          *
  117.          */
  118.         if (argc > 2)
  119.             pbnum(atoi(argv[2]) - 1);
  120.         break;
  121.  
  122.     case SYSCTYPE:
  123.         /*
  124.          * dosys - execute system command
  125.          *
  126.          */
  127.         if (argc > 2)
  128.             sysval = system(argv[2]);
  129.         break;
  130.  
  131.     case SYSVTYPE:
  132.         /*
  133.          * dosysval - return value of the last system call.
  134.          *
  135.          */
  136.         pbnum(sysval);
  137.         break;
  138.  
  139.     case INCLTYPE:
  140.         if (argc > 2)
  141.             if (!doincl(argv[2]))
  142.                 error("M4: Cannot open %s for read",argv[2]);
  143.         break;
  144.  
  145.     case SINCTYPE:
  146.         if (argc > 2)
  147.             (void) doincl(argv[2]);
  148.         break;
  149. #ifdef EXTENDED
  150.     case PASTTYPE:
  151.         if (argc > 2)
  152.             if (!dopaste(argv[2]))
  153.                 error("M4: Cannot open %s for read",argv[2]);
  154.         break;
  155.  
  156.     case SPASTYPE:
  157.         if (argc > 2)
  158.             (void) dopaste(argv[2]);
  159.         break;
  160. #endif
  161.     case CHNQTYPE:
  162.         dochq(argv, argc);
  163.         break;
  164.  
  165.     case CHNCTYPE:
  166.         dochc(argv, argc);
  167.         break;
  168.  
  169.     case SUBSTYPE:
  170.         /*
  171.          * dosub - select substring
  172.          *
  173.          */
  174.         if (argc > 3)
  175.             dosub(argv,argc);
  176.         break;
  177.  
  178.     case SHIFTYPE:
  179.         /*
  180.          * doshift - push back all arguments except the
  181.          *         first one (i.e. skip argv[2])
  182.          */
  183.         if (argc > 3) {
  184.             for (n = argc-1; n > 3; n--) {
  185.                 putback(rquote);
  186.                 pbstr(argv[n]);
  187.                 putback(lquote);
  188.                 putback(',');
  189.             }
  190.             putback(rquote);
  191.             pbstr(argv[3]);
  192.             putback(lquote);
  193.         }
  194.         break;
  195.  
  196.     case DIVRTYPE:
  197.         if (argc > 2)
  198.         {
  199.             n = atoi(argv[2]);
  200.             dodiv(n);
  201.         }
  202.         else
  203.             dodiv(-1);
  204.         break;
  205.  
  206.     case UNDVTYPE:
  207.         doundiv(argv, argc);
  208.         break;
  209.  
  210.     case DIVNTYPE:
  211.         /*
  212.          * dodivnum - return the number of current
  213.          * output diversion
  214.          *
  215.          */
  216.         pbnum(oindex);
  217.         break;
  218.  
  219.     case UNDFTYPE:
  220.         /*
  221.          * doundefine - undefine a previously defined
  222.          *        macro(s) or m4 keyword(s).
  223.          */
  224.         if (argc > 2)
  225.             for (n = 2; n < argc; n++)
  226.                 remhash(argv[n], ALL);
  227.         break;
  228.  
  229.     case POPDTYPE:
  230.         /*
  231.          * dopopdef - remove the topmost definitions of
  232.          *          macro(s) or m4 keyword(s).
  233.          */
  234.         if (argc > 2)
  235.             for (n = 2; n < argc; n++)
  236.                 remhash(argv[n], TOP);
  237.         break;
  238.  
  239.     case MKTMTYPE:
  240.         /*
  241.          * dotemp - create a temporary file
  242.          *
  243.          */
  244.         if (argc > 2)
  245.         {
  246.             pbstr(argv[2]);
  247.             if (*tempdir)
  248.             {
  249.                 putback('.');
  250.                 pbstr(tempdir);
  251.             }
  252.         }
  253.         break;
  254.  
  255.     case TRNLTYPE:
  256.         /*
  257.          * dotranslit - replace all characters in the
  258.          *        source string that appears in
  259.          *        the "from" string with the corresponding
  260.          *        characters in the "to" string.
  261.          *
  262.          */
  263.         if (argc > 3) {
  264.             char temp[MAXTOK];
  265.             if (argc > 4)
  266.                 map(temp, argv[2], argv[3], argv[4]);
  267.             else
  268.                 map(temp, argv[2], argv[3], null);
  269.             pbstr(temp);
  270.         }
  271.         else
  272.             if (argc > 2)
  273.             pbstr(argv[2]);
  274.         break;
  275.  
  276.     case INDXTYPE:
  277.         /*
  278.          * doindex - find the index of the second argument
  279.          *         string in the first argument string.
  280.          *         -1 if not present.
  281.          */
  282.         pbnum((argc > 3) ? indx(argv[2], argv[3]) : -1);
  283.         break;
  284.  
  285.     case ERRPTYPE:
  286.         /*
  287.          * doerrp - print the arguments to stderr file
  288.          *
  289.          */
  290.         if (argc > 2) {
  291.             for (n = 2; n < argc; n++)
  292.                 fprintf(stderr,"%s ", argv[n]);
  293.             fprintf(stderr, "\n");
  294.         }
  295.         break;
  296.  
  297.     case DNLNTYPE:
  298.         /*
  299.          * dodnl - eat-up-to and including newline
  300.          *
  301.          */
  302.         while ((c = gpbc()) != '\n' && c != EOF)
  303.             ;
  304.         break;
  305.  
  306.     case M4WRTYPE:
  307.         /*
  308.          * dom4wrap - set up for wrap-up/wind-down activity
  309.          *
  310.          */
  311.         m4wraps = (argc > 2) ? strsave(argv[2]) : null;
  312.         break;
  313.  
  314.     case EXITTYPE:
  315.         /*
  316.          * doexit - immediate exit from m4.
  317.          *
  318.          */
  319.         exit((argc > 2) ? atoi(argv[2]) : 0);
  320.         break;
  321.  
  322.     case DEFNTYPE:
  323.         if (argc > 2)
  324.             for (n = 2; n < argc; n++)
  325.                 dodefn(argv[n]);
  326.         break;
  327.  
  328.     default:
  329.         error("M4: major botch in eval.");
  330.         break;
  331.     }
  332. }
  333.